package com.to8to.autotask.rpc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.thrift.TException;
import org.elasticsearch.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.to8to.autotask.util.Utils;
import com.to8to.autotask.zbinfo.ZBInfo;
import com.to8to.crm.common.ThriftClientFactory;
import com.to8to.es.util.LogUtil;
import com.to8to.thrift.crm.autotask.AutoTaskService;
import com.to8to.thrift.crm.itemdb.TItemFP;
import com.to8to.thrift.crm.query.AffirmReturnMoneyRequest;
import com.to8to.thrift.crm.query.CompanyInfo;
import com.to8to.thrift.crm.query.MoneyResponse;
import com.to8to.thrift.crm.query.QueryService;
import com.to8to.thrift.crm.query.TakeOutLatePaymentRequest;
import com.to8to.thrift.crm.query.TakeOutMoneyRequest;
import com.to8to.thrift.crm.utils.SelectCityRequest;
import com.to8to.thrift.crm.utils.TCity;
import com.to8to.thrift.crm.utils.TCityResponse;
import com.to8to.thrift.crm.utils.UtilsService;
import com.to8to.thrift.diary.service.SceneDiaryService;
import com.to8to.thrift.sms.SMSService;

/**
 * CallClient.java                               
 * 作 者：atom.liu
 * 版 本：v2.0
 * 日 期：2014年11月26日
 * 描 述：调用ESB其他服务的客户端
 */
public final class CallClient
{
    private static CallClient client = new CallClient();

    private static final Logger logger = LoggerFactory.getLogger(CallClient.class);

    public static CallClient getInstance()
    {
        return client;
    }

    private CallClient()
    {
    }

    public QueryService.Iface getQueryService()
    {
        QueryService.Iface iface = (QueryService.Iface) ThriftClientFactory.getClient(QueryService.class);
        return iface;
    }

    public AutoTaskService.Iface getAutoTaskService()
    {
        AutoTaskService.Iface iface = (AutoTaskService.Iface) ThriftClientFactory.getClient(AutoTaskService.class);
        return iface;
    }

    public SMSService.Iface getSMSService()
    {
        SMSService.Iface iface = (SMSService.Iface) ThriftClientFactory.getClient(SMSService.class);
        return iface;
    }

    public SceneDiaryService.Iface getSceneDiaryService()
    {
        SceneDiaryService.Iface iface = (SceneDiaryService.Iface) ThriftClientFactory.getClient(SceneDiaryService.class);
        return iface;
    }

    public UtilsService.Iface getUtilsService()
    {
        UtilsService.Iface iface = (UtilsService.Iface) ThriftClientFactory.getClient(UtilsService.class);
        return iface;
    }

    /**
     * 获取落地城市列表
     * @return
     */
    public static List<Integer> getLuodiCity()
    {
        List<Integer> cityIds = Lists.newArrayList();
        try
        {
            UtilsService.Iface iface = client.getUtilsService();
            SelectCityRequest req = new SelectCityRequest();
            req.setFields(Arrays.asList(TCity._Fields.ISGROUND.getFieldName()));
            TCity city = new TCity();
            city.setIsground(1);
            req.city = city;
            TCityResponse resp = iface.selectCity(req);
            for (TCity c : resp.citys)
                cityIds.add(c.cityid);
        }
        catch (TException e)
        {
            logger.error("获取落地城市失败！{} \n {}", e, LogUtil.logStackTrace(e));
        }
        logger.info("获取落地城市列表：" + cityIds);
        return cityIds;
    }

    /**
     * 调用远程服务，扣轮单费
     * @param map key：yid，value:List<CompanyInfo> 
     */
    public static void takeOutMoneyFromCompany(Map<Integer, List<CompanyInfo>> map)
    {
        QueryService.Iface service = client.getQueryService();
        for (Map.Entry<Integer, List<CompanyInfo>> entry : map.entrySet())
        {
            TakeOutMoneyRequest req = new TakeOutMoneyRequest();
            req.setYid(entry.getKey());
            req.setCompany_infos(entry.getValue());

            try
            {
                List<MoneyResponse> resps = service.takeOutMoneyFromCompany(req);
                if (isAllSucc(resps))
                    logger.info(String.format("项目  [ %s ] 扣轮单费执行成功 ！ %s", req.getYid(), resps));
                else
                    logger.error(String.format("项目  [ %s ] 扣轮单费存在失败情况！ %s", req.getYid(), resps));

            }
            catch (Throwable e)
            {
                logger.error("调用扣轮单费的服务出现异常！{} \n {}", e, LogUtil.logStackTrace(e));
            }
        }
    }

    /**
     * 调用远程服务，自动返款（返轮单费）
     */
    public static void affirmReturnMoney(Map<Integer, List<TItemFP>> yidMap)
    {
        QueryService.Iface service = client.getQueryService();
        for (Map.Entry<Integer, List<TItemFP>> entry : yidMap.entrySet())
        {
            AffirmReturnMoneyRequest req = new AffirmReturnMoneyRequest();
            req.setYid(entry.getKey());

            List<CompanyInfo> companyInfos = new ArrayList<CompanyInfo>();
            for (TItemFP fp : entry.getValue())
            {
                CompanyInfo info = new CompanyInfo();
                info.setCompanyid(fp.getUid());
                info.setFid(fp.getFid());
                companyInfos.add(info);
            }

            req.setCompany_infos(companyInfos);
            try
            {
                List<MoneyResponse> resps = service.affirmReturnMoney(req);
                logger.info(String.format("项目  [ %s ] 扣轮单费结果：%s", req.getYid(), resps));
            }
            catch (Throwable e)
            {
                logger.error("调用返款接口出现错误！yid: [ {} ], 返款公司信息： [ {} ]！{} \n {}", req.getYid(), companyInfos, e, LogUtil.logStackTrace(e));
            }
        }
    }

    /**
     * 调用ESB服务，自动扣滞纳金
     * @param reqs 扣滞纳金请求参数集合
     */
    public static void takeOutLatePaymentFromCompany(List<TakeOutLatePaymentRequest> reqs)
    {
        QueryService.Iface queryService = client.getQueryService();
        //调用服务完成扣滞纳金
        for (TakeOutLatePaymentRequest req : reqs)
        {
            try
            {
                int result = queryService.takeOutLatePaymentFromCompany(req);
                if (result == 1)
                    logger.info(String.format("扣滞纳金成功！zid：[ %s ]  uid: [ %s ]", req.getZid(), req.getCid()));
                else
                    logger.error(String.format("扣滞纳金失败，Result[ %s ] ！zid：[ %s ]  uid: [ %s ]", result, req.getZid(), req.getCid()));
            }
            catch (Throwable e)
            {
                logger.error("调用扣滞纳金异常!uid: [ {} ],zid: [ {} ]！{} \n {}", req.getCid(), req.getZid(), e.getMessage(), LogUtil.logStackTrace(e));
            }
        }
    }

    /**
     * 调用ESB服务，生成返款记录。
     */
    public static void generateRebateRecord(List<ZBInfo> list)
    {
        QueryService.Iface queryService = client.getQueryService();
        for (ZBInfo req : list)
        {
            try
            {
                int res = queryService.generateSaleFk(req.getZid(), req.getYid(), req.getUid());
                if (res == 1)
                    logger.info(String.format("生成返款记录成功！ zid: [ %s ], yid: [ %s ], uid: [ %s ]", req.getZid(), req.getYid(), req.getUid()));
                else
                    logger.error(String.format("生成返款记录失败,Result[ %s ]！ zid: [ %s ], yid: [ %s ], uid: [ %s ]", res, req.getZid(), req.getYid(), req.getUid()));
            }
            catch (Throwable e)
            {
                logger.error("调用生成返款记录服务出现异常！{} \n {}", e, LogUtil.logStackTrace(e));
            }
        }
    }

    /**
     * 是否全部结果都是成功
     */
    private static boolean isAllSucc(List<MoneyResponse> resps)
    {
        if (Utils.isNullOrEmpty(resps))
            return false;
        for (MoneyResponse resp : resps)
            if (resp.getResult() != 1)
                return false;
        return true;
    }
}
